package kr.co.bnsmedia.touchconfig;

import android.app.Activity;
import android.os.Bundle;
import android.os.Message;
import android.view.Menu;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.TextView;

public class DetectionActivity extends Activity implements View.OnClickListener, IOnHandlerMessage {

	private static final int RADIO_FUNCTION_THRESHOLD = 0;
	private static final int RADIO_FUNCTION_YCENTER = 1;
	private static final int RADIO_FUNCTION_XSTART = 2;
	private static final int RADIO_FUNCTION_XEND = 3;

	private static final int CAMERA_MAIN = 10;	// Camera 1, 2
	private static final int CAMERA_SUB = 11;	// Camera 3, 4

	private static final int HANDLER_DETECTION_START = 1;

	private MyApp mApp = null;
	private WeakRefHandler mHandler = null;
	private DetectionView mDetectioin[] = {null, null, null, null};

	private int mFunctionIdx1 = 0;
	private int mFunctionIdx2 = 0;

	private final int BUTTONS [] = {
			R.id.btn_threshold_1,
			R.id.btn_ycenter_1,
			R.id.btn_xstart_1,
			R.id.btn_xend_1,
			R.id.btn_down_1_10,
			R.id.btn_down_1_1,
			R.id.btn_up_1_1,
			R.id.btn_up_1_10,
			R.id.btn_threshold_2,
			R.id.btn_ycenter_2,
			R.id.btn_xstart_2,
			R.id.btn_xend_2,
			R.id.btn_down_2_10,
			R.id.btn_down_2_1,
			R.id.btn_up_2_1,
			R.id.btn_up_2_10,
			R.id.btn_comfirm,
			R.id.btn_cancel,
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_detection);

		for (int button : BUTTONS) {
			findViewById(button).setOnClickListener(this);
		}
		mDetectioin[0] = (DetectionView)findViewById(R.id.vw_detection_1);
		mDetectioin[1] = (DetectionView)findViewById(R.id.vw_detection_2);
		mDetectioin[2] = (DetectionView)findViewById(R.id.vw_detection_3);
		mDetectioin[3] = (DetectionView)findViewById(R.id.vw_detection_4);

		mApp = (MyApp)getApplication();
		mHandler = new WeakRefHandler((IOnHandlerMessage)this);
		mApp.setHandler(mHandler);

		mFunctionIdx1 = RADIO_FUNCTION_THRESHOLD;
		((CompoundButton)findViewById(R.id.btn_threshold_1)).setChecked(true);
		changeFunction(R.id.btn_threshold_1);
		((TextView)findViewById(R.id.tvw_threshold_1)).setText("" + mApp.cameraConfig(0).bThreshold);
		((TextView)findViewById(R.id.tvw_ycenter_1)).setText("" + mApp.cameraConfig(0).nYCenter);
		((TextView)findViewById(R.id.tvw_xstart_1)).setText("" + mApp.cameraConfig(0).wXStart);
		((TextView)findViewById(R.id.tvw_xend_1)).setText("" + mApp.cameraConfig(0).wXEnd);

		mFunctionIdx2 = RADIO_FUNCTION_THRESHOLD;
		((CompoundButton)findViewById(R.id.btn_threshold_2)).setChecked(true);
		changeFunction(R.id.btn_threshold_2);
		((TextView)findViewById(R.id.tvw_threshold_2)).setText("" + mApp.cameraConfig(1).bThreshold);
		((TextView)findViewById(R.id.tvw_ycenter_2)).setText("" + mApp.cameraConfig(1).nYCenter);
		((TextView)findViewById(R.id.tvw_xstart_2)).setText("" + mApp.cameraConfig(1).wXStart);
		((TextView)findViewById(R.id.tvw_xend_2)).setText("" + mApp.cameraConfig(1).wXEnd);

		changeCamera(CAMERA_MAIN);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();

	}

	@Override
	public void onClick(View arg0) {
		final int fId = arg0.getId();

		switch (fId) {
		case R.id.btn_threshold_1:
		case R.id.btn_ycenter_1:
		case R.id.btn_xstart_1:
		case R.id.btn_xend_1:
		case R.id.btn_threshold_2:
		case R.id.btn_ycenter_2:
		case R.id.btn_xstart_2:
		case R.id.btn_xend_2:
			changeFunction(fId);
			break;
		case R.id.btn_down_1_10:
			changeValue(true, -10);
			break;
		case R.id.btn_down_1_1:
			changeValue(true, -1);
			break;
		case R.id.btn_up_1_1:
			changeValue(true, 1);
			break;
		case R.id.btn_up_1_10:
			changeValue(true, 10);
			break;
		case R.id.btn_down_2_10:
			changeValue(false, -10);
			break;
		case R.id.btn_down_2_1:
			changeValue(false, -1);
			break;
		case R.id.btn_up_2_1:
			changeValue(false, 1);
			break;
		case R.id.btn_up_2_10:
			changeValue(false, 10);
			break;
		case R.id.btn_comfirm:
		case R.id.btn_cancel:
			mHandler.sendMessage(Message.obtain(mHandler, HANDLER_DETECTION_START,
					g.device.CAMERA1, ((R.id.btn_comfirm == fId) ? RESULT_OK : RESULT_CANCELED)));
			break;
		}
	}

	@Override
	public void handleMessage(Message msg) {
		switch (msg.what) {
		case MyApp.HANDLER_RESULT:
			handlerResult(msg.arg1, msg.arg2, (byte[])msg.obj);
			break;
		case MyApp.HANDLER_EVENT:
			handlerEvent(msg.arg1, msg.arg2, (byte[])msg.obj);
			break;

		case HANDLER_DETECTION_START:
			if ((g.device.CAMERA1 + g.device.MAX_CAMERA) == msg.arg1) {
				if (CAMERA_MAIN == msg.arg2) {
					byte[] start = {1};
					mApp.wirtePacket(g.command.DETECTION_START, (byte)g.device.CAMERA1, (byte)start.length, start);
					mApp.wirtePacket(g.command.DETECTION_START, (byte)g.device.CAMERA2, (byte)start.length, start);
				} else if (CAMERA_MAIN == msg.arg2) {
					byte[] start = {1};
					mApp.wirtePacket(g.command.DETECTION_START, (byte)g.device.CAMERA3, (byte)start.length, start);
					mApp.wirtePacket(g.command.DETECTION_START, (byte)g.device.CAMERA4, (byte)start.length, start);
				} else {
					setResult(msg.arg2);
					finish();
				}
			} else {
				byte[] stop = {0};
				mApp.wirtePacket(g.command.DETECTION_START, (byte)(msg.arg1), (byte)stop.length, stop);
				mHandler.sendMessageDelayed(Message.obtain(mHandler, HANDLER_DETECTION_START, (msg.arg1 + 1), msg.arg2), 100);
			}
			break;
		}
	}


	private void handlerResult(int aDev, int aDlen, byte[] aData) {
		int command = (int)(aData[0] & 0xFF);

		switch (command) {
		case g.command.SET_THRESHOLD:
			if ((g.device.CAMERA1 == aDev) || (g.device.CAMERA3 == aDev)) {
				((TextView)findViewById(R.id.tvw_threshold_1)).setText("" + mApp.cameraConfig(aDev - g.device.CAMERA1).bThreshold);
			} else if ((g.device.CAMERA2 == aDev) || (g.device.CAMERA4 == aDev)) {
				((TextView)findViewById(R.id.tvw_threshold_2)).setText("" + mApp.cameraConfig(aDev - g.device.CAMERA1).bThreshold);
			}
			mDetectioin[aDev - g.device.CAMERA1].setThreshold(mApp.cameraConfig(aDev - g.device.CAMERA1).bThreshold);
			break;
		case g.command.SET_YCENTER:
			if ((g.device.CAMERA1 == aDev) || (g.device.CAMERA3 == aDev)) {
				((TextView)findViewById(R.id.tvw_ycenter_1)).setText("" + mApp.cameraConfig(aDev - g.device.CAMERA1).nYCenter);
			} else if ((g.device.CAMERA2 == aDev) || (g.device.CAMERA4 == aDev)) {
				((TextView)findViewById(R.id.tvw_ycenter_2)).setText("" + mApp.cameraConfig(aDev - g.device.CAMERA1).nYCenter);
			}
			mDetectioin[aDev - g.device.CAMERA1].reset();
			break;
		case g.command.SET_XSTART:
			if ((g.device.CAMERA1 == aDev) || (g.device.CAMERA3 == aDev)) {
				((TextView)findViewById(R.id.tvw_xstart_1)).setText("" + mApp.cameraConfig(aDev - g.device.CAMERA1).wXStart);
			} else if ((g.device.CAMERA2 == aDev) || (g.device.CAMERA4 == aDev)) {
				((TextView)findViewById(R.id.tvw_xstart_2)).setText("" + mApp.cameraConfig(aDev - g.device.CAMERA1).wXStart);
			}
			mDetectioin[aDev - g.device.CAMERA1].setXStart(mApp.cameraConfig(aDev - g.device.CAMERA1).wXStart);
			break;
		case g.command.SET_XEND:
			if ((g.device.CAMERA1 == aDev) || (g.device.CAMERA3 == aDev)) {
				((TextView)findViewById(R.id.tvw_xend_1)).setText("" + mApp.cameraConfig(aDev - g.device.CAMERA1).wXEnd);
			} else if ((g.device.CAMERA2 == aDev) || (g.device.CAMERA4 == aDev)) {
				((TextView)findViewById(R.id.tvw_xend_2)).setText("" + mApp.cameraConfig(aDev - g.device.CAMERA1).wXEnd);
			}
			mDetectioin[aDev - g.device.CAMERA1].setXEnd(mApp.cameraConfig(aDev - g.device.CAMERA1).wXEnd);
			break;

		case g.command.DETECTION_START:
			break;
		}
	}

	private void handlerEvent(int aCmdDev, int aDlen, byte[] aData) {
		int command = (aCmdDev>>16) & 0xFFFF;
		int device = aCmdDev & 0xFF;

		switch (command) {
		case g.command.EVT_IMAGE_DETECTION:
			mDetectioin[device - g.device.CAMERA1].setData(device, aDlen, aData);
			break;
		}
	}

	private void changeCamera(int type) {
		if (CAMERA_MAIN == type) {
			mDetectioin[0].setVisibility(View.VISIBLE);
			mDetectioin[0].setThreshold(mApp.cameraConfig(0).bThreshold);
			mDetectioin[0].setXStart(mApp.cameraConfig(0).wXStart);
			mDetectioin[0].setXEnd(mApp.cameraConfig(0).wXEnd);

			mDetectioin[1].setVisibility(View.VISIBLE);
			mDetectioin[1].setThreshold(mApp.cameraConfig(1).bThreshold);
			mDetectioin[1].setXStart(mApp.cameraConfig(1).wXStart);
			mDetectioin[1].setXEnd(mApp.cameraConfig(1).wXEnd);

			mDetectioin[2].setVisibility(View.INVISIBLE);
			mDetectioin[3].setVisibility(View.INVISIBLE);
		} else if (CAMERA_SUB == type) {
			mDetectioin[0].setVisibility(View.INVISIBLE);
			mDetectioin[1].setVisibility(View.INVISIBLE);

			mDetectioin[2].setVisibility(View.VISIBLE);
			mDetectioin[2].setThreshold(mApp.cameraConfig(2).bThreshold);
			mDetectioin[2].setXStart(mApp.cameraConfig(2).wXStart);
			mDetectioin[2].setXEnd(mApp.cameraConfig(2).wXEnd);

			mDetectioin[3].setVisibility(View.VISIBLE);
			mDetectioin[3].setThreshold(mApp.cameraConfig(3).bThreshold);
			mDetectioin[3].setXStart(mApp.cameraConfig(3).wXStart);
			mDetectioin[3].setXEnd(mApp.cameraConfig(3).wXEnd);
		}

		mHandler.sendMessage(Message.obtain(mHandler, HANDLER_DETECTION_START, g.device.CAMERA1, type));
		for (int i=0; i<mDetectioin.length; i++) {
			mDetectioin[i].reset();
		}
	}

	private void changeFunction(int id) {
		switch (id) {
		case R.id.btn_threshold_1:
			mFunctionIdx1 = RADIO_FUNCTION_THRESHOLD;
			((CompoundButton)findViewById(R.id.btn_ycenter_1)).setChecked(false);
			((CompoundButton)findViewById(R.id.btn_xstart_1)).setChecked(false);
			((CompoundButton)findViewById(R.id.btn_xend_1)).setChecked(false);
			break;
		case R.id.btn_ycenter_1:
			mFunctionIdx1 = RADIO_FUNCTION_YCENTER;
			((CompoundButton)findViewById(R.id.btn_threshold_1)).setChecked(false);
			((CompoundButton)findViewById(R.id.btn_xstart_1)).setChecked(false);
			((CompoundButton)findViewById(R.id.btn_xend_1)).setChecked(false);
			break;
		case R.id.btn_xstart_1:
			mFunctionIdx1 = RADIO_FUNCTION_XSTART;
			((CompoundButton)findViewById(R.id.btn_threshold_1)).setChecked(false);
			((CompoundButton)findViewById(R.id.btn_ycenter_1)).setChecked(false);
			((CompoundButton)findViewById(R.id.btn_xend_1)).setChecked(false);
			break;
		case R.id.btn_xend_1:
			mFunctionIdx1 = RADIO_FUNCTION_XEND;
			((CompoundButton)findViewById(R.id.btn_threshold_1)).setChecked(false);
			((CompoundButton)findViewById(R.id.btn_ycenter_1)).setChecked(false);
			((CompoundButton)findViewById(R.id.btn_xstart_1)).setChecked(false);
			break;

		case R.id.btn_threshold_2:
			mFunctionIdx2 = RADIO_FUNCTION_THRESHOLD;
			((CompoundButton)findViewById(R.id.btn_ycenter_2)).setChecked(false);
			((CompoundButton)findViewById(R.id.btn_xstart_2)).setChecked(false);
			((CompoundButton)findViewById(R.id.btn_xend_2)).setChecked(false);
			break;
		case R.id.btn_ycenter_2:
			mFunctionIdx2 = RADIO_FUNCTION_YCENTER;
			((CompoundButton)findViewById(R.id.btn_threshold_2)).setChecked(false);
			((CompoundButton)findViewById(R.id.btn_xstart_2)).setChecked(false);
			((CompoundButton)findViewById(R.id.btn_xend_2)).setChecked(false);
			break;
		case R.id.btn_xstart_2:
			mFunctionIdx2 = RADIO_FUNCTION_XSTART;
			((CompoundButton)findViewById(R.id.btn_threshold_2)).setChecked(false);
			((CompoundButton)findViewById(R.id.btn_ycenter_2)).setChecked(false);
			((CompoundButton)findViewById(R.id.btn_xend_2)).setChecked(false);
			break;
		case R.id.btn_xend_2:
			mFunctionIdx2 = RADIO_FUNCTION_XEND;
			((CompoundButton)findViewById(R.id.btn_threshold_2)).setChecked(false);
			((CompoundButton)findViewById(R.id.btn_ycenter_2)).setChecked(false);
			((CompoundButton)findViewById(R.id.btn_xstart_2)).setChecked(false);
			break;
		}
	}

	private void changeValue(boolean isTop, int offset) {
		int cameraIdx, functionIdx, newValue;

		if (isTop) {
			cameraIdx = 0;	// 0 or 2
			functionIdx = mFunctionIdx1;
		} else {
			cameraIdx = 1;	// 1 or 3
			functionIdx = mFunctionIdx2;
		}

		switch (functionIdx) {
		case RADIO_FUNCTION_THRESHOLD:
			newValue = mApp.cameraConfig(cameraIdx).bThreshold + offset;
			if (g.DATA_THRESHOLD_MIN > newValue) {
				newValue = g.DATA_THRESHOLD_MIN;
			} else if (g.DATA_THRESHOLD_MAX < newValue) {
				newValue = g.DATA_THRESHOLD_MAX;
			}
			if (mApp.cameraConfig(cameraIdx).bThreshold != newValue) {
				byte[] threshold = {(byte)newValue};
				mApp.wirtePacket(g.command.SET_THRESHOLD, (byte)(g.device.CAMERA1 + cameraIdx), (byte)threshold.length, threshold);
			}
			break;
		case RADIO_FUNCTION_YCENTER:
			newValue = mApp.cameraConfig(cameraIdx).nYCenter + offset;
			if (g.DATA_YCENTER_MIN > newValue) {
				newValue = g.DATA_YCENTER_MIN;
			} else if (g.DATA_YCENTER_MAX < newValue) {
				newValue = g.DATA_YCENTER_MAX;
			}
			if (mApp.cameraConfig(cameraIdx).nYCenter != newValue) {
				byte[] yCenter = PacketData.uShortToByteArray(newValue);
				mApp.wirtePacket(g.command.SET_YCENTER, (byte)(g.device.CAMERA1 + cameraIdx), (byte)yCenter.length, yCenter);
			}
			break;
		case RADIO_FUNCTION_XSTART:
			newValue = mApp.cameraConfig(cameraIdx).wXStart + offset;
			if (g.DATA_XSTART_MIN > newValue) {
				newValue = g.DATA_XSTART_MIN;
			} else if (g.DATA_XSTART_MAX < newValue) {
				newValue = g.DATA_XSTART_MAX;
			}
			if (mApp.cameraConfig(cameraIdx).wXStart != newValue) {
				byte[] xStart = PacketData.uShortToByteArray(newValue);
				mApp.wirtePacket(g.command.SET_XSTART, (byte)(g.device.CAMERA1 + cameraIdx), (byte)xStart.length, xStart);
			}
			break;
		case RADIO_FUNCTION_XEND:
			newValue = mApp.cameraConfig(cameraIdx).wXEnd + offset;
			if (g.DATA_XEND_MIN > newValue) {
				newValue = g.DATA_XEND_MIN;
			} else if (g.DATA_XEND_MAX < newValue) {
				newValue = g.DATA_XEND_MAX;
			}
			if (mApp.cameraConfig(cameraIdx).wXEnd != newValue) {
				byte[] xEnd = PacketData.uShortToByteArray(newValue);
				mApp.wirtePacket(g.command.SET_XEND, (byte)(g.device.CAMERA1 + cameraIdx), (byte)xEnd.length, xEnd);
			}
			break;
		}
	}
}
